package csx.study.demo.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.InvalidKeyException;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.Map;

public class JwtUtils {

    /**
     * 生成jwt
     * 使用HS256算法, 私钥使用固定秘钥
     *
     * @param secretKey jwt秘钥（至少32字符）
     * @param ttlMillis jwt过期时间(毫秒)
     * @param claims    设置的信息
     * @return
     * @throws InvalidKeyException 如果密钥长度不足
     */
    public static String createJWT(String secretKey, long ttlMillis, Map<String, Object> claims) {
        // 验证密钥长度
        if (secretKey.getBytes(StandardCharsets.UTF_8).length < 32) {
            throw new InvalidKeyException("密钥长度必须至少为256位(32字符)");
        }

        Key key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        // 设置过期时间
        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);

        // 构建JWT
        JwtBuilder builder = Jwts.builder()
                .claims(claims)  // 新版直接设置claims
                .signWith(key)    // 自动识别算法
                .expiration(exp);

        return builder.compact();
    }

    /**
     * Token解密
     *
     * @param secretKey jwt秘钥（至少32字符）
     * @param token     加密后的token
     * @return
     * @throws InvalidKeyException 如果密钥长度不足
     */
    public static Claims parseJWT(String secretKey, String token) {
        // 验证密钥长度
        if (secretKey.getBytes(StandardCharsets.UTF_8).length < 32) {
            throw new InvalidKeyException("密钥长度必须至少为256位(32字符)");
        }

        SecretKey key = Keys.hmacShaKeyFor(secretKey.getBytes(StandardCharsets.UTF_8));

        return Jwts.parser()
                .verifyWith(key)  // 设置验证密钥
                .build()
                .parseSignedClaims(token)
                .getPayload();  // 直接获取Claims主体
    }

}